package info_serv

import (
	"strconv"
	"strings"
	"ubt-aio-service/app/mod/info_mod"
	"ubt-aio-service/app/pkg/db"
	"ubt-aio-service/app/utils"
)

type infoServ struct{}

var InfoServ = infoServ{}

// Add 新增资讯
func (s *infoServ) Add(req *info_mod.InfoSaveReq) *utils.ResJson {
	sqlStr := `INSERT INTO information(fst_title, sec_title, kind, info_type, sort, src, begin_time, end_time, cmted, describ, 
		contents, fst_img_id, fst_img_name, fst_img_url, img_ids, img_names, img_urls, file_ids, file_names, file_urls, 
		visit_num, good_num, cmt_num, tag_ids, tag_names, states, add_time, upd_time) 
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, 
		$23, $24, $25, 3, EXTRACT(epoch FROM NOW()), EXTRACT(epoch FROM NOW()))`
	return db.CudData(sqlStr, req.FstTitle, req.SecTitle, req.Kind, req.InfoType, req.Sort, req.Src, req.BeginTime, req.EndTime,
		req.Cmted, req.Describ, req.Contents, req.FstImgId, req.FstImgName, req.FstImgUrl, req.ImgIds, req.ImgNames, req.ImgUrls,
		req.FileIds, req.FileNames, req.FileUrls, req.VisitNum, req.GoodNum, req.CmtNum, req.TagIds, req.TagNames)
}

// Exists 判断资讯编码是否存在
func (s *infoServ) Exists(req *info_mod.InfoExtVo) bool {
	sqlStr := "SELECT info_id FROM information WHERE states IN (1, 3) AND info_type=$1 AND fst_title=$2"
	param := make([]any, 0)
	param = append(param, req.InfoType)
	param = append(param, req.FstTitle)
	if req.InfoId != "" {
		sqlStr += " AND info_id!=$3"
		param = append(param, req.InfoId)
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code {
		return true
	}
	return false
}

// Update 修改资讯
func (s *infoServ) Update(req *info_mod.InfoSaveReq) *utils.ResJson {
	sqlStr := `UPDATE information SET fst_title=$1, sec_title=$2, kind=$3, info_type=$4, sort=$5, src=$6, begin_time=$7, 
		end_time=$8, cmted=$9, describ=$10, contents=$11, fst_img_id=$12, fst_img_name=$13, fst_img_url=$14, img_ids=$15, 
		img_names=$16, img_urls=$17, file_ids=$18, file_names=$19, file_urls=$20, visit_num=$21, good_num=$22, 
		cmt_num=$23, tag_ids=$24, tag_names=$25, upd_time=EXTRACT(epoch FROM NOW()) WHERE info_id=$26`
	return db.CudData(sqlStr, req.FstTitle, req.SecTitle, req.Kind, req.InfoType, req.Sort, req.Src, req.BeginTime, req.EndTime,
		req.Cmted, req.Describ, req.Contents, req.FstImgId, req.FstImgName, req.FstImgUrl, req.ImgIds, req.ImgNames, req.ImgUrls,
		req.FileIds, req.FileNames, req.FileUrls, req.VisitNum, req.GoodNum, req.CmtNum, req.TagIds, req.TagNames, req.InfoId)
}

// Process 删除资讯
func (s *infoServ) Process(req *info_mod.InfoProReq) *utils.ResJson {
	var (
		param []any
		q     string
		n     = 1
	)
	param = append(param, req.States)
	idList := strings.Split(req.InfoIds, ",")
	for _, curId := range idList {
		n++
		q += "$" + strconv.Itoa(n) + ","
		param = append(param, curId)
	}
	q = q[:len(q)-1]
	sqlStr := "UPDATE information SET states=$1, upd_time=EXTRACT(epoch FROM NOW()) WHERE info_id IN (" + q + ")"
	return db.CudData(sqlStr, param...)
}

// One 获取资讯详情
func (s *infoServ) One(roleId string) *utils.ResJson {
	sqlStr := `SELECT a.info_id, a.fst_title, a.sec_title, a.kind, a.info_type, a.sort, a.src, a.begin_time, a.end_time, 
		a.cmted, a.describ, a.contents, a.fst_img_id, a.fst_img_name, a.fst_img_url, a.img_ids, a.img_names, a.img_urls, 
		a.file_ids, a.file_names, a.file_urls, a.visit_num, a.good_num, a.cmt_num, a.tag_ids, a.tag_names, a.states, 
		a.add_time, a.upd_time, b.dict_name AS type_name, b.dict_code AS type_code 
		FROM information a LEFT JOIN sys_dict b ON b.kind=2 AND a.info_type=b.dict_id WHERE a.info_id=$1`
	return db.GetOne(sqlStr, roleId)
}

// Count 获取资讯数量
func (s *infoServ) Count(req *info_mod.InfoPageReq) *utils.ResJson {
	sqlStr := "SELECT COUNT(1) AS nums FROM information WHERE states IN (1, 3) AND kind=$1"
	var param []any
	param = append(param, req.Kind)
	var n = 1
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "fst_title LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"sec_title LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"tag_names LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 3
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.InfoType != "" {
		n++
		sqlStr += " AND info_type=$" + strconv.Itoa(n)
		param = append(param, req.InfoType)
	}
	if req.States != 0 {
		n++
		sqlStr += " AND states=$" + strconv.Itoa(n)
		param = append(param, req.States)
	}
	if req.BeginDate != 0 {
		n++
		sqlStr += " AND begin_time>=$" + strconv.Itoa(n)
		param = append(param, req.BeginDate)
	}
	if req.EndDate != 0 {
		n++
		sqlStr += " AND end_time<=$" + strconv.Itoa(n)
		param = append(param, req.EndDate)
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code && res.Data.(map[string]any)["nums"].(int64) > 0 {
		return res
	}
	return utils.NoData
}

// Page 获取资讯分页列表
func (s *infoServ) Page(req *info_mod.InfoPageReq) *utils.ResJson {
	sqlStr := "SELECT a.info_id, a.fst_img_url, a.fst_title, b.dict_name, a.begin_time, a.end_time, a.states " +
		"FROM information a LEFT JOIN sys_dict b ON b.kind=2 AND a.info_type=b.dict_id " +
		"WHERE a.states IN (1, 3) AND a.kind=$1"
	var param []any
	param = append(param, req.Kind)
	var n = 1
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "a.fst_title LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"a.sec_title LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"a.tag_names LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 3
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.InfoType != "" {
		n++
		sqlStr += " AND a.info_type=$" + strconv.Itoa(n)
		param = append(param, req.InfoType)
	}
	if req.States != 0 {
		n++
		sqlStr += " AND a.states=$" + strconv.Itoa(n)
		param = append(param, req.States)
	}
	if req.BeginDate != 0 {
		n++
		sqlStr += " AND a.begin_time>=$" + strconv.Itoa(n)
		param = append(param, req.BeginDate)
	}
	if req.EndDate != 0 {
		n++
		sqlStr += " AND a.end_time<=$" + strconv.Itoa(n)
		param = append(param, req.EndDate)
	}
	sqlStr += " ORDER BY a.upd_time DESC LIMIT $" + strconv.Itoa(n+1) + " OFFSET $" + strconv.Itoa(n+2)
	param = append(param, req.Limit)
	param = append(param, req.Offset)
	return db.GetAll(sqlStr, param...)
}

// Sort 获取资讯数量，用于排序
func (s *infoServ) Sort(infoType string) *utils.ResJson {
	sqlStr := "SELECT COUNT(1)+1 AS nums FROM information WHERE states IN (1, 3) AND info_type=$1"
	res := db.GetOne(sqlStr, infoType)
	return &utils.ResJson{Code: utils.Succeed.Code, Msg: utils.Succeed.Msg, Data: res.Data.(map[string]any)["nums"].(int64)}
}
